class Range {
  final int start;
  final int end;

  Range(this.start, this.end);

  int get length => end - start + 1;

  int indexOf(int value) => value - start;

  bool contains(int value) => value >= start && value <= end;

  bool containsRange(Range range) => contains(range.start) && contains(range.end);

  bool intersects(Range range) => contains(range.start) || contains(range.end);

  @override
  bool operator ==(Object other) {
    if (other is Range) {
      return start == other.start && end == other.end;
    }
    return false;
  }

  @override
  int get hashCode => start.hashCode ^ end.hashCode;

  @override
  String toString() => 'Range($start, $end)';
}

extension NumRangeExtension<T extends num> on T {
  T clampToRange(Range range) {
    return clamp(range.start, range.end) as T;
  }
}
